package com.sojson.util.mq.rabbit.immit.interfaces;

import java.io.IOException;
import java.util.Map;

import org.springframework.amqp.core.AmqpAdmin;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.CustomExchange;

import com.sojson.util.mq.rabbit.interfaces.IRabbitBaseExchangeUtil;

/**
 * Rabbit声明交换机工具类接口
 * 
 * @author liu
 * @date 2022-06-16
 */
public interface IRabbitExchangeUtil extends IRabbitBaseExchangeUtil {

    /**
     * 获取一个交换机
     * 
     * @param exchange  交换机名称
     * @return
     * @throws IOException
     */
    default CustomExchange getExchange(String exchange) throws IOException {
        return getExchange(exchange, true, false, false, getExchangeParam());
    }

    /**
     * 获取一个交换机
     * 
     * @param exchange      交换机名称
     * @param durable       消息是否持久化(默认为false)
     * @param autoDelete    当交换机不再使用时,是否自动删除它(默认为false)
     * @param internal      设置是否内置的,如果设置为true,则表示是内置的交换器(默认为false)</BR>
     *                      客户端程序无法直接发送消息到这个交换器中,只能通过交换器路由到交换器这种方式</BR>
     * @return
     * @throws IOException
     */
    default CustomExchange getExchange(String exchange, boolean durable, boolean autoDelete, boolean internal)
        throws IOException {
        return getExchange(exchange, durable, autoDelete, internal, getExchangeParam());
    }

    /**
     * 获取一个交换机
     * 
     * @param exchange      交换机名称
     * @param durable       消息是否持久化(默认为false)
     * @param autoDelete    当交换机不再使用时,是否自动删除它(默认为false)
     * @param internal      设置是否内置的,如果设置为true,则表示是内置的交换器(默认为false)</BR>
     *                      客户端程序无法直接发送消息到这个交换器中,只能通过交换器路由到交换器这种方式</BR>
     * @param arguments     交换机参数(默认为null)
     * @return
     * @throws IOException
     */
    default CustomExchange getExchange(String exchange, boolean durable, boolean autoDelete, boolean internal,
        Map<String, Object> arguments) throws IOException {
        CustomExchange customExchange =
            new CustomExchange(getExchangeName(exchange), getExchangeType(), durable, autoDelete, arguments);
        customExchange.setInternal(internal);
        return customExchange;
    }

    /**
     * 声明一个交换机
     * 
     * @param channel
     * @param exchange  交换机名称
     * @return
     * @throws IOException
     */
    default CustomExchange exchangeDeclare(AmqpAdmin channel, String exchange) throws IOException {
        return exchangeDeclare(channel, getExchange(exchange));
    }

    /**
     * 声明一个交换机
     * 
     * @param channel
     * @param exchange      交换机名称
     * @param durable       消息是否持久化(默认为false)
     * @param autoDelete    当交换机不再使用时,是否自动删除它(默认为false)
     * @param internal      设置是否内置的,如果设置为true,则表示是内置的交换器(默认为false)</BR>
     *                      客户端程序无法直接发送消息到这个交换器中,只能通过交换器路由到交换器这种方式</BR>
     * @return
     * @throws IOException
     */
    default CustomExchange exchangeDeclare(AmqpAdmin channel, String exchange, boolean durable, boolean autoDelete,
        boolean internal) throws IOException {
        return exchangeDeclare(channel, getExchange(exchange, durable, autoDelete, internal));
    }

    /**
     * 声明一个交换机
     * 
     * @param channel
     * @param exchange      交换机名称
     * @param durable       消息是否持久化(默认为false)
     * @param autoDelete    当交换机不再使用时,是否自动删除它(默认为false)
     * @param internal      设置是否内置的,如果设置为true,则表示是内置的交换器(默认为false)</BR>
     *                      客户端程序无法直接发送消息到这个交换器中,只能通过交换器路由到交换器这种方式</BR>
     * @param arguments     交换机参数(默认为null)
     * @return
     * @throws IOException
     */
    default CustomExchange exchangeDeclare(AmqpAdmin channel, String exchange, boolean durable, boolean autoDelete,
        boolean internal, Map<String, Object> arguments) throws IOException {
        return exchangeDeclare(channel, getExchange(exchange, durable, autoDelete, internal, arguments));
    }

    /**
     * 声明一个交换机
     * 
     * @param channel
     * @param exchange  交换机
     * @return
     * @throws IOException
     */
    default CustomExchange exchangeDeclare(AmqpAdmin channel, CustomExchange exchange) throws IOException {
        LOG.info("开始声明Rabbit交换机: " + exchange.getName() + ", 类型: " + exchange.getType() + ", 参数: "
            + exchange.getArguments());
        channel.declareExchange(exchange);
        return exchange;
    }

    /**
     * 将交换机和队列绑定
     * 
     * @param channel
     * @param binding   绑定对象
     * @return
     * @throws IOException
     */
    default Binding queueBind(AmqpAdmin channel, Binding binding) throws IOException {
        LOG.info("开始绑定Rabbit交换机和队列,交换机: " + binding.getExchange()
            + ", 队列: " + binding.getDestination() + ", RoutingKey: " + binding.getRoutingKey() + ", 参数: "
            + binding.getArguments());
        channel.declareBinding(binding);
        return binding;
    }

}